
#include <QCoreApplication>
#include <QTimer>
#include <QDebug>

#if defined(Q_OS_WIN) || defined(Q_CC_MINGW)
#include <windows.h>
#endif

#include "utils.h"

Utils::Utils(QObject *parent) : QObject{parent}
{
}

void Utils::ExitAfter(qint32 msec)
{
    QTimer *timer = new QTimer(qApp);
    QObject::connect(timer, &QTimer::timeout, qApp, &QCoreApplication::quit);
    timer->start(msec);
}

void Utils::HandelSignal(qint32 signal_number, SignalHandlerCallback callback)
{
    Q_UNUSED(signal_number)
    Q_UNUSED(callback)

#if defined(Q_OS_LINUX) || defined(Q_CC_MINGW)
    signal(signal_number, callback);
#endif
}

void Utils::m_sleep(quint32 ms)
{
    if (ms > 0) {
#if defined (Q_OS_WIN)
        Sleep(ms);
#else
        usleep(ms * 1000);
#endif
    }
}

bool Utils::AttachOutputToConsole(void)
{
#if defined(Q_OS_WIN)
    HANDLE ConsoleHandleOut, ConsoleHandleError;
    DWORD OriginalOutMode = 0, OriginalErrorMode = 0;
    DWORD RequestedModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;

    if (AttachConsole(ATTACH_PARENT_PROCESS)) {
        // Redirect unbuffered STDOUT to the console
        ConsoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE);
        if (ConsoleHandleOut != INVALID_HANDLE_VALUE) {
            freopen("CONOUT$", "w", stdout);
            setvbuf(stdout, nullptr, _IONBF, 0);
            GetConsoleMode(ConsoleHandleOut, &OriginalOutMode);
            SetConsoleMode(ConsoleHandleOut, OriginalOutMode | RequestedModes);
        } else {
            return false;
        }
        // Redirect unbuffered STDERR to the console
        ConsoleHandleError = GetStdHandle(STD_ERROR_HANDLE);
        if (ConsoleHandleError != INVALID_HANDLE_VALUE) {
            freopen("CONOUT$", "w", stderr);
            setvbuf(stderr, nullptr, _IONBF, 0);
            GetConsoleMode(ConsoleHandleError, &OriginalErrorMode);
            SetConsoleMode(ConsoleHandleError, OriginalErrorMode | RequestedModes);
        } else {
            return false;
        }
        return true;
    }
    // Not a console application
    return false;
#else
    return true;
#endif
}
